
#include <iostream>
#include "web_server.h"
#include "getopt_pp/getopt_pp.h"
#include "configfile.h"
#include "fs/path.h"

void show_usage()
{
	std::cout << "usage: coming soon" << std::endl;
}

bool fill_params( int argc, char* argv[], Params *pparams, MimeTypes *pmimetypes )
{
	using namespace GetOpt;
	using namespace config;
	Params p;
	bool help_flag = false;
	
	GetOpt_pp ops(argc, argv);
	ops >> OptionPresent( 'h', "help", help_flag ); 
	if( help_flag )
	{
		show_usage();
		return false;
	}

	ops >> Option( 'c', "configfile",	p.configfile,	p.configfile );
	ops >> Option( 'm', "mimefile",		p.mimefile,		p.mimefile	 );

	if( pparams->configfile.is_exist() )
	{
		ConfigFile cf( pparams->configfile );
		cf.get_value( "host",		&p.host,		p.host		);
		cf.get_value( "port",		&p.port,		p.port		);
		cf.get_value( "root",		&p.root,		p.root		);
		cf.get_value( "index",		&p.index,		p.index		);
		cf.get_value( "autoindex",	&p.autoindex,	p.autoindex	);
		cf.get_value( "nocache",	&p.nocache,		p.nocache	);
		cf.get_value( "hideme",		&p.hideme,		p.hideme	);
	}

	typedef unsigned short ushr;
	ops >> Option		( 'o', "host",		p.host,		 p.host		 );
	ops >> Option<ushr>	( 'p', "port",		p.port,		 p.port		 );
	ops >> Option		( 'r', "root",		p.root,		 p.root		 );
	ops >> Option		( 'i', "index",		p.index,	 p.index	 );
	ops >> Option<bool>	( 'a', "autoindex",	p.autoindex, p.autoindex );
	ops >> Option<bool>	( 'n', "nocache",	p.nocache,	 p.nocache	 );
	ops >> Option<bool>	( 'd', "hideme",	p.hideme,	 p.hideme	 );

	MimeTypes mimetypes;
	if( pparams->mimefile.is_exist() )
	{
		ConfigFile cf( pparams->mimefile );
		for( ConfigFile::const_iterator it = cf.begin(); 
			it != cf.end();
			++it )
		{
			mimetypes.update( it->first, it->second );
		}

	}

	*pmimetypes = mimetypes;
	*pparams = p;

}

int main(int argc, char* argv[]) 
{
	try 
	{
		Params params;
		MimeTypes mimetypes;

		fill_params( argc, argv, &params, &mimetypes );

		WebServer webserver( params, mimetypes );
		webserver.run();
	} 
	catch( GetOpt::GetOptEx & e )
	{
		std::cout << "invalid command line syntax near " << e.what() << std::endl;
		show_usage();
		return 1;
	}
	catch( config::ConfigFileEx & e )
	{
		std::cout << "invalid config file: " << e.what() << std::endl;
		show_usage();
		return 1;	
	}
	catch( std::exception & e )
	{
		std::cout << "runtime error " << e.what() << std::endl;
		return 1;		
	}

	getchar();
	return 0;
};